#include "merge.h"
#include "config.h"
#include "tablemapping.h"

Merge::Merge(TableMapping &tableMapping, Oracle::Connection &connection):Load(tableMapping, connection)
{
}

int Merge::load()
{
	return Load::load();
}

int Merge::createSql()
{
	bool first = true, first2 = true;
	size_t i, j;
	const Table &tagetTable = tableMapping.getTargetTable();
	map<string, string> &mapping = tableMapping.getMap();
	map<string, string>::const_iterator iter;
	char tmp[1024];
	string insertCols, insertValues;

	const Index *key = tableMapping.getTargetKey();
	if (key == 0){
		error<<"can not find primary key or unique index "<<endl;
		return -1;
	}
	
	sql  = "merge into ";
	sql += tableMapping.getTargetTable().getName();
	sql += " a using ";
	sql += tableMapping.getSourceTable().getName();
	sql += " b on (";
	for (i=0; i<key->indexColumns.size(); i++){
		if (!first){
			sql += " and ";
		}
		first = false;
		
		if (tagetTable.colNullable(key->indexColumns[i].name)){
			sprintf(tmp, "((a.%s=%s) or (a.%s is null and %s is null))", 
				key->indexColumns[i].name.c_str(), mapping[key->indexColumns[i].name].c_str(),
				key->indexColumns[i].name.c_str(), mapping[key->indexColumns[i].name].c_str());
		}else{
			sprintf(tmp, "(a.%s=%s)", key->indexColumns[i].name.c_str(), mapping[key->indexColumns[i].name].c_str());
		}
		sql += tmp;		
	}
	
	insertCols = " (";
	insertValues = "(";
	
	sql += ") when matched then update set ";
	for (iter=mapping.begin(),first=true,first2=true; iter!=mapping.end(); iter++){
		for (j=0; j<key->indexColumns.size(); j++){
			if (iter->first == key->indexColumns[j].name){
				break;
			}
		}
		if (!first2){
			insertCols += ",";
			insertValues += ",";
		}
		first2 = false;
		if (j < key->indexColumns.size()){	//column is a part of unique Index
			sprintf(tmp, "a.%s", iter->first.c_str());
			insertCols += tmp;

			sprintf(tmp, "%s", iter->second.c_str());
			insertValues += tmp;
			continue;
		}
		
		if (!first){
			sql += ",";
		}
		first = false;
		
		sprintf(tmp, "a.%s=%s", iter->first.c_str(),iter->second.c_str());
		sql += tmp;
		
		sprintf(tmp, "a.%s", iter->first.c_str());
		insertCols += tmp;
		
		sprintf(tmp, "%s", iter->second.c_str());
		insertValues += tmp;
	}
	insertCols += ") ";
	insertValues += ") ";
	
	sql += " when not matched then insert ";
	sql += insertCols;
	sql += "values";
	sql += insertValues;
		
	return 0;
}
